using System;
using LaughingDog;
using LaughingDog.Components;
using LaughingDog.GameObjects;
using LaughingDog.Input;
using LaughingDog.Managers;
using Microsoft.Xna.Framework;

namespace LaughingDog.Scripts
{
    public class TurnToFacePoint : Script
    {
        private Vector2 mTarget = Vector2.Zero;
        private Single mTurnSpeed = 1;

        /// <summary>
        /// Gets or sets a value indicating the position the GameObject will rotate to.
        /// </summary>
        public Vector2 Target { get { return mTarget; } set { mTarget = value; } }

        /// <summary>
        /// Gets or sets a value specifying the maximum rotation speed in which the GameObject can achieve when attempting to reach the target.
        /// </summary>
        public Single TurnSpeed { get { return mTurnSpeed; } set { mTurnSpeed = value; } }

        /// <summary>
        /// Creates a new instance of a TurnToFacePoint script component.
        /// </summary>
        /// <param name="gameObject">The GameObject that this component should be attached to.</param>
        public TurnToFacePoint(GameObject gameObject)
            : base(gameObject)
        {

        }

        /// <summary>
        /// Updates this component.
        /// </summary>
        public override void Update()
        {
            Single x = mTarget.X - Transform.Position.X;
            Single y = mTarget.Y - Transform.Position.Y;

            Single desiredAngle = (Single)Math.Atan2(y, x);
            desiredAngle += MathHelper.ToRadians(90);

            Single difference = WrapAngle(desiredAngle - Transform.RotationRadians);

            difference = MathHelper.Clamp(difference, -mTurnSpeed, mTurnSpeed);

            Transform.RotationRadians = WrapAngle(Transform.RotationRadians + difference);            

            base.Update();
        }

        private static float WrapAngle(Single rotation)
        {
            while (rotation < -MathHelper.Pi)
            {
                rotation += MathHelper.TwoPi;
            }
            while (rotation > MathHelper.Pi)
            {
                rotation -= MathHelper.TwoPi;
            }

            return rotation;
        }
    }
}